/*
 * Copyright (c) csii.com.cn 2016 zhaojin
 */

package com.csii.ssm.dto;

import com.csii.ssm.exception.AccessRuntimeException;
import com.csii.ssm.exception.AccessRuntimeExceptionDict;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;

/**
 * @author zhaojin 15398699939@163.com
 * @create 2016-08-13-12:10
 */
@Component("resubmitTokenManager")
@Scope
public class ResubmitTokenManager {

    private int maxEntryNumber = 3;
    //token有效时间（秒）,默认10分钟
    private int delayTime = 600;
    //session中存储的TokenList的key
    private String tokenListName = "_DCTOKENLIST";
    //session中存储的Token的uniqueId的key
    private String tokenName = "_tokenName";
    private int tokenLength = 8;
    Logger logger = LoggerFactory.getLogger(ResubmitTokenManager.class);
    private boolean ignoreCase = false;

    public Token createToken(HttpSession httpSession) {
        TokenList localTokenList = (TokenList) httpSession.getAttribute(this.tokenListName);
        if (localTokenList == null) {
            localTokenList = new TokenList(this.maxEntryNumber, this.delayTime, this.tokenLength);
            httpSession.setAttribute(this.tokenListName, localTokenList);
        }
        String uniqueId = localTokenList.getNextTokenId();
        if (this.ignoreCase) {
            uniqueId = uniqueId.replaceAll("0", "1");
            uniqueId = uniqueId.replaceAll("o", "p");
            uniqueId = uniqueId.replaceAll("1", "2");
            uniqueId = uniqueId.replaceAll("l", "m");
        }
        TokenImpl localTokenImpl = new TokenImpl(uniqueId, System.currentTimeMillis(), delayTime);
        localTokenList.add(localTokenImpl);
        httpSession.setAttribute(this.tokenName, localTokenImpl.getUniqueId());
        if (logger.isDebugEnabled())
            logger.debug("Create Token" + this.tokenListName + "," + this.tokenName + " " + localTokenImpl);
        return localTokenImpl;
    }


    public void verifyToken(HttpSession httpSession, Token token) throws AccessRuntimeException {
        if (null == token || StringUtils.isEmpty(token.getUniqueId())) {
            throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_VERIFYTOKEN_REQTOKENUNIQUEID);
        }
        verifyToken(httpSession, token.getUniqueId());
    }

    public void verifyToken(HttpSession httpSession, String reqTokenUniqueId) throws AccessRuntimeException {
        TokenList localTokenList = (TokenList) httpSession.getAttribute(this.tokenListName);
        if (logger.isDebugEnabled())
            logger.debug("Verify Token" + this.tokenListName + "," + this.tokenName + " " + localTokenList);
        if (localTokenList == null)
            throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_VERIFYTOKENREQ);
        if (reqTokenUniqueId == null)
            throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_VERIFYTOKEN_REQTOKENUNIQUEID);
        if (this.ignoreCase)
            reqTokenUniqueId = reqTokenUniqueId.toLowerCase();
        try {
            Token localToken = localTokenList.get(reqTokenUniqueId);
            if (localToken != null) {
                logger.info("Token校验成 {}", localToken);
            } else {
                throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_VERIFYTOKENREQ_FAIL);
            }
        } catch (Exception localException) {
            logger.error("校验token错误!", localException);
            throw new AccessRuntimeException(localException);
        }
    }

    public void setDelayTime(int delayTime) {
        this.delayTime = delayTime;
    }

    public void setMaxEntryNumber(int maxEntryNumber) {
        this.maxEntryNumber = maxEntryNumber;
    }

    public void setTokenListName(String tokenListName) {
        this.tokenListName = tokenListName;
    }

    public void setTokenName(String tokenName) {
        this.tokenName = tokenName;
    }

    public void setTokenLength(int tokenLength) {
        this.tokenLength = tokenLength;
    }

    public void setIgnoreCase(boolean ignoreCase) {
        this.ignoreCase = ignoreCase;
    }
}
